home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Freeware 2001 May
/
SGI Freeware 2001 May - Disc 1.iso
/
dist
/
patchSG0003743.idb
/
usr
/
include
/
ffio.h.z
/
ffio.h
Wrap
C/C++ Source or Header
|
2001-04-12
|
58KB
|
1,943 lines
/* USMID @(#) clibinc/ffio.h 92.6 09/22/99 16:30:21 */
/*
*
* Copyright 1997, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
/*
* (C) COPYRIGHT CRAY RESEARCH, INC.
* UNPUBLISHED PROPRIETARY INFORMATION.
* ALL RIGHTS RESERVED.
*/
/*
* FFIO definitions, macros, and prototypes
*/
#ifndef _FFIO_H
#define _FFIO_H
#include <clibdefs.h>
#include <sys/types.h> /* ffc_stat_s structure field declarations */
#include <cray/fortio.h> /* unum_t typedef */
#if defined(__mips)
#include <aio.h>
#elif defined(_LITTLE_ENDIAN)
/* do not include pthread.h for little endian systems */
#else
#include <cray/libuni.h> /* for _LIB_UMK, used in fflistreq declaration*/
#endif
/*
* read/write record processing modes
*/
#define PARTIAL 0
#define FULL 1
/*
* Status values for sw_status
*/
#define FFBSY 0
#define FFCNT 1
#define FFEOR 2
#define FFEOF 3
#define FFEOD 4
#define FFBOD 5
#define FFERR 6
/*
* Command codes for fffcntl calls
* Values: 0 - reserved for FORTRAN 'get fio pointer'
* 1-99 reserved for CRI built-in layers
* 100-199 reserved for user layers
* 200-299 reserved for site layers
*/
#define FC_GETINFO 1
#define FC_STAT 2
#define FC_SETRECL 3
#define FC_RECALL 4
#define FC_ACPTBAD 5
#define FC_SKIPBAD 6
#define FC_GETTP 7
#define FC_AUTOBAD 8
#define FC_CHECKTP 9
#define FC_ENDSP 10
#define FC_STARTSP 11
#define FC_CLOSEV 12
#define FC_SETSP 13
#define FC_ASPOLL 14 /* give recall a shot at cleanup, no wait */
#define FC_SCRATCH 15 /* identify a file as a scratch file */
#define FC_TSYNC 16 /* sync a tape file */
#define FC_DUMPSTATS 17 /* dump intermediate layer statistics */
#define FC_TPC_SDBSZ 18 /* change block size on ER90 */
#define FC_IALLOC 19 /* bottom layer call ialloc */
#define FC_GETLK 20 /* get file lock */
#define FC_SETLK 21 /* set file lock */
#define FC_SETLKW 22 /* set file lock wait */
#define FC_FSTATFS 23 /* bottom layer call fstatfs */
#define FC_DIOINFO 24 /* get direct info (IRIX only) */
#define FC_CHECKEOV 25 /* check end-of-volume status (IRIX only) */
#define FC_TSDATA 26 /* get tape status information (IRIX only) */
/*
* Mask bits for return word in FC_GETINFO fffcntl call
*/
#define FFC_STRM 0x00000001 /* can handle stream I/O */
#define FFC_REC 0x00000002 /* can handle records */
#define FFC_WEOF 0x00000004 /* can represent EOF */
#define FFC_WEOD 0x00000008 /* can represent EOD (all can do) */
#define FFC_BKSP 0x00000010 /* can handle backspace */
#define FFC_BKFIL 0x00000020 /* can handle backfile */
#define FFC_SEEKA 0x00000040 /* can seek absolute */
#define FFC_SEEKR 0x00000080 /* can seek relative */
#define FFC_SEEKE 0x00000100 /* can seek to end */
#define FFC_POSREC 0x00000200 /* can position by record number */
#define FFC_POSFIL 0x00000400 /* can position by EOF mark */
#define FFC_RWND 0x00000800 /* can rewind by seek(x,0,0) */
#define FFC_FIXD 0x00001000 /* can do fixed len recs */
#define FFC_VAR 0x00002000 /* can do variable len recs */
#define FFC_BINARY 0x00004000 /* can do binary records */
#define FFC_CODED 0x00008000 /* can do formatted records */
#define FFC_RDM 0x00010000 /* can do random I/O (no trunc) */
#define FFC_SEQ 0x00020000 /* can do sequential I/O */
#define FFC_ASYNC 0x00040000 /* can do asynchronous I/O */
#define FFC_WRTRUNC 0x00080000 /* write implies truncation */
#define FFC_NOTRN 0x00100000 /* Does no transformation on data */
/* hence, 'backdoor' ops can be OK */
#define FFC_BCKDOOR 0x00200000 /* Can handle O_SSD flag on open call */
#define FFC_SKIPBAD 0x00400000 /* Can skip bad data */
#define FFC_NOCLOSE 0x00800000 /* Don't try to close layer on abort */
#define FFC_CANLISTIO 0x01000000 /* The layer has a listio entry */
#define FFC_CANSYLISTIO 0x02000000 /* The layer has a listio entry that */
/* is capable of limited listio */
/*
* Command codes for POS calls
*/
#define FP_GETPOS 1 /* get position of file */
#define FP_SETPOS 2 /* set position of file */
#define FP_BSEEK 3 /* seek to bit position */
#define FP_BKSP 4 /* back up one record (BACKSPACE) */
#define FP_BKFIL 5 /* back up one file (BACKFILE) */
#define FP_GETREC 6 /* Get current record number */
#define FP_SETREC 7 /* Set position to specified record number */
#define FP_SKIPF 8 /* Skip file (SKIPF) */
#define FP_SETTP 9 /* set position of tape file (SETTP) */
#define FP_POS0 10 /* "position to current position" */
#define FP_RSEEK 11 /* relative seek */
#define FP_SKIPTPMK 12 /* skip tape mark */
#define FP_GABS 13 /* get absolute position */
#define FP_SABS 14 /* set absolute position */
#define FP_GETTAPEPOS 15 /* get tape position (IRIX only) */
#define FP_SETTAPEPOS 16 /* set tape position (IRIX only) */
/*
* Codes used to indicate direction/meaning for some positioning requests
*/
#define FP_TPOS_ABS 0 /* absolute */
#define FP_TPOS_FORW 1 /* forward */
#define FP_TPOS_BACK 2 /* backwards */
/*
* Argument values for FC_AUTOBAD fffcntl request
*/
#define AUTO_SKIP 1 /* skip 1 block of bad data */
#define AUTO_ACPT 2 /* accept bad data */
#define AUTO_SKIPALL 3 /* skip all bad data */
/*
* Flag values for FC_SCRATCH fffcntl request status word.
*/
#define SCR_SINGLELINK 1 /* file is regular and not a linked file */
#define SCR_UNLINKED 2 /* an unlink() successfully deleted the file */
#define SCR_NOFLUSH 4 /* ffclose() buffer flushing suppressed */
/*
* Return the I/O status from an operation.
*/
#define FFSTAT(io_sw) ((io_sw).sw_stat)
/*
* Status return: This structure is used in all internal calls to return
* status. The first word is made compatible with the iosw for use
* with async I/O.
*/
struct ffsw
{
unsigned int sw_flag:1;
unsigned int sw_error:31;
#ifdef __mips
size_t sw_count;
#else
unsigned int sw_count:32;
#endif
unsigned int sw_stat:16; /* FFCNT, etc. */
#if defined(_WORD32) || defined(__mips) || defined(_LITTLE_ENDIAN)
int sw_user:32; /* For user layer storage */
#else
int sw_user:48; /* For user layer storage */
#endif
#if defined(_ADDR64) || defined(__mips) || defined(_LITTLE_ENDIAN)
void *sw_iptr; /* pointer to layer data */
void *sw_sptr; /* pointer to status chain, if used. */
#else
int sw_iptr:32; /* pointer to layer data */
int sw_sptr:32; /* pointer to status chain, if used. */
#endif
int sw_rsv1; /* may need later. Save space now */
#ifdef __mips
aiocb_t aiocbp;
#endif
#ifdef _EXTRA_FFSW_STUFF
_EXTRA_FFSW_STUFF /* for internal Cray applications use */
#endif
};
/*
* fffcntl FC_GETINFO structure
*/
struct ffc_info_s
{
long ffc_flags; /* flag word */
int ffc_gran; /* minimum granularity, no. bits in smallest */
/* I/O possible. (bits/bytes/words) */
int ffc_reclen; /* Record length (in bits) */
int ffc_fd; /* Lowest level file desc, -1 if invalid */
int ffc_poslen:16; /* GETPOS/SETPOS pos array length */
#if defined(_WORD32) || defined(__mips) || defined(_LITTLE_ENDIAN)
int unused1:16; /* reserved */
#else
int unused1:48; /* reserved */
#endif
int unused2; /* reserved */
};
/*
* fffcntl FC_SKIPBAD or FC_ACPTBAD structure
*/
struct ffc_baddata_s
{
int ffc_termcnd; /* position after handling bad data */
int ffc_blocks; /* number of blocks skipped */
int ffc_bytes; /* number of bytes accepted */
int ffc_maxflag; /* 1 if maximum number of words to accept */
int ffc_maxwords; /* maximum number of words to accept */
long ffc_uda; /* address of area to store data */
int unused1; /* reserved */
int unused2; /* reserved */
};
/*
* fffcntl FC_GETTP structure
*/
struct ffc_gettp_s
{
int ffc_glen; /* number of words to copy to ffc_pa */
int ffc_synch; /* 1 = synch, 0 = do not. Only after write */
#if defined(__mips) || defined(_LITTLE_ENDIAN)
long long *ffc_pa;/* info copied here */
#else
long *ffc_pa; /* info copied here */
#endif
int unused1; /* reserved */
int unused2; /* reserved */
};
/*
* fffcntl FC_CHECKTP structure
*/
struct ffc_chktp_s
{
int stat; /* status of tape */
int libblk; /* Number of blocks in library */
int unused1; /* reserved */
int unused2; /* reserved */
};
/*
* fffcntl FC_CHECKEOV structure
*/
struct ffc_chkev_s
{
int stat; /* status of tape: 1 = at eov */
int bufblk; /* Number of buffered whole blocks */
size_t bufbytes; /* number of bytes unwritten from last record
on the tape */
int unused1; /* reserved */
int unused2; /* reserved */
};
/*
* fffcntl FC_STAT structure
*
* This is a copy of the stat structure defined in <sys/stat.h>.
* Matches stat structure for:
*
* UNICOS 8.0
* UNICOS-MAX 1.0
* Solaris 5.3
*/
#ifdef _UNICOS
struct ffc_stat_s
{
dev_t st_dev;
ino_t st_ino;
mode_t st_mode;
nlink_t st_nlink;
uid_t st_uid;
gid_t st_gid;
dev_t st_rdev;
off_t st_size;
time_t st_atime;
long st_spare1; /* Reserved for microsec time stamps */
time_t st_mtime;
long st_spare2; /* Reserved for microsec time stamps */
time_t st_ctime;
long st_spare3; /* Reserved for microsec time stamps */
_SHORTPAD
unsigned short st_acid; /* Accounting id */
#if defined(_CRAY1) || defined(_CRAYMPP)
long st_count; /* Reference count */
off_t st_msize; /* Modification size for signature */
#endif /* _CRAY1 || _CRAYMPP */
unsigned int st_msref : 1, /* Modification signature referenced */
st_ms :31, /* Modification signature */
st_gen :32; /* Generation number */
#if defined(_CRAY1) || defined(_CRAYMPP)
/*18*/
long st_blocks; /* #of sectors allocated to file */
long st_blksize; /* Optimal small I/O xfer size (bytes)*/
long st_oblksize; /* Optimal large I/O xfer size (bytes)*/
long st_allocf; /* Allocation flags */
long st_cblks; /* Cluster blocks (Cray-YMP) */
long st_cbits; /* Cluster bits */
long st_param[8]; /* 8-pack track/sector addresses */
long st_spareparam[4]; /* Reserved for additional pack */
#endif /* _CRAY1 || _CRAYMPP */
/*36*/
/* data migration fields */
_SHORTPAD
unsigned short st_dm_mode; /* actual file mode */
unsigned int
st_dm_port : 3, /* migrated file daemon port */
st_dm_state : 5, /* migrated file state */
st_dm_status: 56; /* migrated file status flags */
long st_dm_mid; /* migrated file machine id */
long st_dm_key; /* migrated file key */
/*40*/
/* security fields */
unsigned int : 62,
st_hasacl : 1, /* File has an ACL */
st_hascomps : 1; /* File has compartments */
_SHORTPAD
short st_slevel; /* file level */
_SHORTPAD
short st_secflg; /* security flags */
_SHORTPAD
short st_intcls; /* integrity class */
_SHORTPAD
short st_intcat; /* integrity category */
/*45*/
long st_site; /* site field from inode */
long st_nindir; /* # of indirect extent blocks */
long st_resv_pad[6]; /* reserved pad space to 53 words */
};
#elif defined(_SOLARIS)
#include <sys/time.h>
struct ffc_stat_s {
dev_t st_dev;
long st_pad1[3];
ino_t st_ino;
mode_t st_mode;
nlink_t st_nlink;
uid_t st_uid;
gid_t st_gid;
dev_t st_rdev;
long st_pad2[2];
off_t st_size;
long st_pad3;
timestruc_t st_atim;
timestruc_t st_mtim;
timestruc_t st_ctim;
long st_blksize;
long st_blocks;
char st_fstype[16 /* == _ST_FSTYPSZ */ ];
long st_pad4[8];
};
#elif defined(__mips)
#include <sys/stat.h>
#ifdef _TIMESTRUCT_T
#define _TIMESTRUCT_FFIO timestruct_t
#else
#define _TIMESTRUCT_FFIO timespec_t
#endif
struct ffc_stat_s {
dev_t st_dev;
long st_pad1[3]; /* reserved for network id */
ino_t st_ino;
mode_t st_mode;
nlink_t st_nlink;
uid_t st_uid;
gid_t st_gid;
dev_t st_rdev;
long st_pad2[2]; /* dev and off_t expansion */
off_t st_size;
long st_pad3; /* future off_t expansion */
_TIMESTRUCT_FFIO st_atim;
_TIMESTRUCT_FFIO st_mtim;
_TIMESTRUCT_FFIO st_ctim;
long st_blksize;
blkcnt_t st_blocks;
char st_fstype[_ST_FSTYPSZ];
long st_pad4[8]; /* expansion area */
};
#elif defined(_LITTLE_ENDIAN)
#include <sys/stat.h>
struct ffc_stat_s {
dev_t st_dev;
unsigned short st_pad1[1];
ino_t st_ino;
mode_t st_mode;
nlink_t st_nlink;
uid_t st_uid;
gid_t st_gid;
dev_t st_rdev;
unsigned short st_pad2[1];
off_t st_size;
long st_blksize;
long st_blocks;
time_t st_atim;
unsigned long unused1[1];
time_t st_mtim;
unsigned long unused2[1];
time_t st_ctim;
unsigned long unused3[1];
unsigned long unused4[1];
unsigned long unused5[1];
};
#endif /* __mips */
/*
* fffcntl FC_IALLOC structure
*/
struct ff_ialloc_struct
{
long ia_nb;
int ia_flag;
int ia_part;
int ia_avl;
int ia_ret;
int ia_before;
};
/*
* FP_SKIPF structure
*/
struct ffp_skipf_s
{
int ffp_nfil; /* number of files to skip (input and output) */
int ffp_nrec; /* number of records skipped (optional output)*/
};
/*
* FP_SETTP structure
*/
struct ffp_settp_s
{
int ffp_nbs_p; /* forward, backward or absolute nb */
long ffp_nb; /* number of blocks (always positive) */
int ffp_nvs_p; /* forward, backward or absolute nv */
int ffp_nv; /* number of volumes (always positive) */
#if defined(__mips)
__int64_t ffp_vi; /* volume identifier */
#elif defined(_LITTLE_ENDIAN)
long long ffp_vi; /* volume identifier */
#else
long ffp_vi; /* volume identifier */
#endif
int unused1; /* reserved */
int unused2; /* reserved */
};
/*
* FP_SKIPTPMK structure
*/
struct ffp_skiptpmk_s
{
int ffp_ntpmk; /* number of tpmks to skip (input and output) */
int unused1; /* reserved */
};
/*
* FP_GABS and FP_SABS structure
*/
struct ffp_abs
{
#if defined(__mips)
__int64_t ffp_absaddr;
#elif defined(_LITTLE_ENDIAN)
long long ffp_absaddr;
#else
long ffp_absaddr;
#endif
int ffp_partition;
int ffp_filesec;
int ffp_datablock;
};
/*
* FP_GETTAPEPOS and FP_SETTAPEPOS structures
*/
struct ffp_tapepos
{
int ffp_type;
int ffp_blockno;
#if defined(__mips)
__int64_t ffp_vsn;
#elif defined(_LITTLE_ENDIAN)
long long ffp_vsn;
#else
long ffp_vsn;
#endif
int ffp_resvd[4];
};
/*
* fflistio request structure, similar to def in <sys/listio.h>
*/
#if defined(__mips) || defined(_LITTLE_ENDIAN)
struct fflistreq
{
int li_opcode; /* operation code */
int li_drvr:32, /* driver dependent */
li_flags:32; /* request flags */
off_t li_offset; /* starting byte offset */
int li_fildes; /* file descriptor (returned by ffopen)*/
char *li_buf; /* buffer address */
size_t li_nbyte; /* bytes per stride count */
struct ffsw *li_status; /* status structure */
int li_signo; /* signal to send upon completion */
int li_nstride; /* number of strides */
off_t li_filstride; /* file stride length in bytes */
size_t li_memstride; /* buffer stride length in bytes */
struct fdinfo *li_ffioptr; /* for use by library routines */
};
#else
struct fflistreq
{
int li_opcode; /* operation code */
int li_drvr:32, /* driver dependent */
li_flags:32; /* request flags */
long li_offset; /* starting byte offset */
int li_fildes; /* file descriptor (FFIO pointer) */
char *li_buf; /* buffer address */
long li_nbyte; /* bytes per stride count */
struct ffsw *li_status; /* status structure */
int li_signo; /* signal to send upon completion */
int li_nstride; /* number of strides */
long li_filstride; /* file stride length in bytes */
long li_memstride; /* buffer stride length in bytes */
#ifdef _LIB_UMK
#ifndef _CRAY1
int li_remote_vpe; /* distio vpe number */
int li_pad[3]; /* mpp extensions */
#endif
#endif
};
#endif
#ifdef _LIB_INTERNAL /* defs below are not for user consumption */
#include <cray/portdefs.h>
#ifndef _TRUE
#define _TRUE 1
#endif
#ifndef _FALSE
#define _FALSE 0
#endif
#define NO 0
#define NONE 0
#define YES 1 /* it is important that this is 1 */
/*
* Change this anytime the format of the environment variables changes.
*/
#define ASG_VERSION 1
#if defined(_WORD32) || defined(__mips) || defined(_LITTLE_ENDIAN)
#define MAGIC_ID 0x2d464443 /* '-FDC' only 4 chars per int */
#else
#define MAGIC_ID '--*FDC--'
#endif
/*
* The following is a macro to change a CAL symbol declaration into a
* value usable by C.
*/
#define _VALUE(xtern) ((int)(&(xtern)))
/*
* General directions
* These are the constants that are used to keep track of the state of
* the I/O.
*/
#define READIN 1 /* last op was READ */
#define WRITIN 2 /* last op was WRITE */
#define POSITIN 4 /* last op was POSITION */
/*
* Record Translation classes
* Note: All of the conversion types for IBM and VMS can be grouped into
* two classes. The Fixed length record type, and the Variable
* length record type. These types differ within the broad
* group according to the existence of blocking, control words,
* and padding.
*
* When adding new classes, be sure to look in libu/ffio/fxrmisc.c and update
* ownopen[] and in fxrmain.c update _recfm_tab[]
*/
#define CLASS_END 0 /* End of chain marker. This is a dummy layer */
/* that is always tacked on the end of spec. */
/* It selects an appropriate handler. */
/* depending on the device. */
#define CLASS_SYSCALL 1 /* handlers for UNIX/stream record model */
#define CLASS_NULL 2 /* explicit NULL layer, does nothing */
#define CLASS_SYSTEM 3 /* same as End of Chain, above */
#define CLASS_COS 4 /* COS blocking */
#define CLASS_BMX 5 /* TAPE handlers */
#define CLASS_F 6 /* FIXED length, no control words */
#define CLASS_V 7 /* variable length, control words */
/* as prefixes only */
#define CLASS_TEXT 8 /* records terminated by 'special character' */
#define CLASS_X 9 /* records with control words as both */
/* prefix and suffix on each record */
#define CLASS_CDC 10 /* CDC class */
#define CLASS_SDS 11 /* SDS handlers */
#define CLASS_MR 12 /* memory resident layer */
#define CLASS_TRACE 13 /* TRACE handlers. Debug tool for 1 file */
#define CLASS_USER 14
#define CLASS_SITE 15
#define CLASS_ERROR 16 /* error layer */
#define CLASS_FD 17 /* user specified file descriptor */
#define CLASS_BLX 18 /* blank expand/compress layer */
#define CLASS_CACHE 19 /* cache layer */
#define CLASS_ER90B 20 /* ER90 byte-stream layer */
#define CLASS_BUFA 21 /* bufa layer */
#define CLASS_CACHEA 22 /* cachea layer */
#define CLASS_EVENT 23 /* event layer */
#define CLASS_LOCK 24 /* lock layer - CRI internal use */
#define CLASS_GLOBAL 25 /* global layer (mpp systems only) */
#define CLASS_F77 26 /* f77 layer */
#define CLASS_TMF 27 /* tmf layer */
#define CLASS_CMP 28 /* compression layer */
#define CLASS_USER0 30
#define CLASS_USER1 31
#define CLASS_USER2 32
#define CLASS_USER3 33
#define CLASS_USER4 34
#define CLASS_USER5 35
#define CLASS_USER6 36
#define CLASS_USER7 37
#define CLASS_USER8 38
#define CLASS_USER9 39
#define NUM_CLASSES 40
/*
* Get definitions of error numbers.
*/
#include <liberrno.h>
/*
* Status returns
*/
#define ERR -1
/*
* ===== Define operation(s) on bit pointers =====
*/
/*
* typedefs
*/
/*
* The bitptr is the basic pointer for use by the FDC routines.
*
* For CRAY-2 and CX/CEA machines, it is a word pointer shifted
* left 6 bits, with the bit offset in the lower 6 bits.
*
* For the CRAY-T3D, CRAY-T3E, and MIPS 64-bit architectures it is a character
* pointer shifted left 3 bits, with the bit offset in the lower 3 bits.
*
* For 32-bit architectures, it is a 64 bit word that is a 32 bit
* character pointer shifted left 3 bits, with the bit offset in
* the lower 3 bits.
*/
#ifdef __mips
typedef __int64_t bitptr;
#elif defined(_WORD32) || defined(_LITTLE_ENDIAN)
typedef long long bitptr;
#else
typedef long bitptr;
#endif
/*
* GET_BPTR()
* Get the raw value of a bit pointer into a word.
*/
#define GET_BPTR(value,bit_ptr) (value) = (bit_ptr)
/*
* SET_BPTR()
* Set a bit pointer to a value
*/
#define SET_BPTR(bit_ptr,value) (bit_ptr) = (value)
/*
* INC_BPTR()
* increment a bit pointer.
*/
#define INC_BPTR(bit_ptr,inc) ((bitptr)(bit_ptr) + (bitptr)(inc))
/*
* SUBT_BPTR(bptr1, bptr2)
* Subtract bptr2 from bptr1 and return a number of bits
*/
#define SUBT_BPTR(bptr1, bptr2) ((bitptr)(bptr1) - (bitptr)(bptr2))
/*
* BPTR2WP()
* Convert a bit pointer to a C word pointer
*/
#ifdef _WORD32
#define BPTR2WP(bptr) ((long *)(((long)((bitptr)(bptr) >> 3)) & ~0x3))
#elif defined (_CRAYMPP) || (_MIPS_SZLONG == 64)
#define BPTR2WP(bptr) ((long *)(((long)(bptr) >> 3) & ~0x7))
#else
#define BPTR2WP(bptr) ((long *)((long)(bptr) >> 6))
#endif
/*
* BPTR2CP()
* Convert a bit pointer to a C character pointer
*/
#if defined (_CRAYMPP) || defined (_WORD32) || defined(__mips) || \
defined(_LITTLE_ENDIAN)
#define BPTR2CP(bptr) ((char *)((long)((bitptr)(bptr) >> 3)))
#else
#define BPTR2CP(bptr) \
((char *)(_dshiftr((long)(bptr), (long)(bptr), 6) & 0xe3ffffffffffffff))
#endif
/*
* WPTR2BP()
* Convert a C word pointer to a bit ptr
*/
#if defined (_CRAYMPP) || defined (_WORD32) || defined(__mips) || \
defined(_LITTLE_ENDIAN)
#define WPTR2BP(wp) (((bitptr)((long)((char *)(wp)))) << 3)
#else
#define WPTR2BP(wp) ((long)(((long)((char *)(wp))) << 6))
#endif
/*
* CPTR2BP()
* Convert a C character pointer to a bit ptr
*/
#if defined (_CRAYMPP) || defined (_WORD32) || defined(__mips) || \
defined(_LITTLE_ENDIAN)
#define CPTR2BP(cptr) (((bitptr)(long)(char *)(cptr)) << 3)
#else
#define CPTR2BP(cptr) ((long)_dshiftl((long)(cptr), (long)(cptr), 6))
#endif
/*
* BPTR2DWP()
* Convert a bit ptr to a 64-bit-word ptr
*/
#ifdef _WORD32
#define BPTR2DWP(bptr) ((long *)(((long)((bitptr)(bptr) >> 3)) & ~0x7))
#elif defined (_CRAYMPP) || (_MIPS_SZLONG == 64)
#define BPTR2DWP(bptr) ((long *)(((long)(bptr) >> 3) & ~0x7))
#else
#define BPTR2DWP(bptr) ((long *)((long)(bptr) >> 6))
#endif
/*
* BPBITOFF(bitptr)
* Return the bit offset within the current word.
*/
#ifdef _WORD32
#define BPBITOFF(bptr) (long) ((bitptr)(bptr) & 0x1fLL)
#else
#define BPBITOFF(bptr) ((long)(bptr) & 0x3f)
#endif
/*
* BPDWBITOFF(bitptr)
* Return the bit offset within the current 64-bit word.
*/
#ifdef _WORD32
#define BPDWBITOFF(bptr) (long) ((bitptr)(bptr) & 0x3fLL)
#else
#define BPDWBITOFF(bptr) ((long)(bptr) & 0x3f)
#endif
/*
* NUMARG()
* Get the number of words passed in the argument list of the current
* function.
*/
#ifdef _UNICOS
#define NUMARG(x) x = _numargs()
#endif
/*
* Get the IO info block for a file descriptor
*/
#if !defined(__mips) && !defined(_LITTLE_ENDIAN)
#define GETIOB(x) (struct fdinfo *)(x)
#else
extern struct fdinfo *_cnvrt2fdinfo(int _fd);
#define GETIOB(x) _cnvrt2fdinfo(x)
#endif
/*
* XRCALL is a simple macro that allows control of the mechanism that
* handles the function pointer references. It also allows us to
* insert debugging code at build time.
*/
#if defined(DEBUG) && !defined(__mips) && !defined(_LITTLE_ENDIAN)
#define XRCALL(fio,ptrname) _xrtrace((fio), (fio)->xr.ptrname,#ptrname,
#else
#define XRCALL(fio,ptrname) (fio)->xr.ptrname(
#endif
/*
* Add check for fdinfo pointer.
*/
#define CHECK_FIOPTR(fio, stat) \
{ \
if (fio == (struct fdinfo *)0L || fio == (struct fdinfo *)-1L || \
fio->magic != MAGIC_ID) \
{ \
errno = FDC_ERR_BADPTR; \
ERETURN(stat, FDC_ERR_BADPTR, 0); \
} \
}
/*
* Debugging stuff
*/
#define FDCTRACE(bit) ((__fdctrace_enable & (bit)) != 0)
/*
* bit defines for debug output
*/
#define TRACE_CALLS 0x001
#define TRACE_STATUS 0x002
#define TRACE_ASG 0x004
#define TRACE_OPEN 0x008
#define TRACE_COS 0x010
#define TRACE_SDSIO 0x020
#define TRACE_WA 0x040
#define TRACE_CACHE 0x080
#define TRACE_SYS 0x100
/*
* IS_RESERVED_FC evaluates to:
* 1 if the fffcntl function code is one reserved for site or user layers.
* 0 otherwise.
*/
#define IS_RESERVED_FC(x) (100 <= (x) && (x) <= 299)
/*
* DUMP_IOB dumps out the IOB in human readable format for
* debugging. It is conditionally compiled and is a no-op
* in normal use.
*/
#if defined(DEBUG) && !defined(__mips) && !defined(_LITTLE_ENDIAN)
#define DUMP_IOB(fio) \
{ \
if (FDCTRACE(TRACE_OPEN)) \
{ \
_xrt_putf("DUMP_IOB: fio=%o B %d - rfd=%o B %d, nfio=%o\n",\
fio, fio, (fio)->realfd, (fio)->realfd, \
(fio)->fioptr); \
_xrt_putf("DUMP_IOB:\trtype=%d, mxr=%d, mbs=%d\n", \
(fio)->rtype, \
(fio)->maxrecsize, (fio)->maxblksize); \
_xrt_putf("DUMP_IOB:\tbase=%o, bufsize=%o\n", \
(fio)->_base, (fio)->_ffbufsiz); \
} \
}
#define GTRACEBACK() TRBK()
#define EQ ==
#define NE !=
#define LT <
#define GT >
#define LE <=
#define GE >=
#define SANITYCHK(aarg,rel,bbarg) \
if (aarg rel bbarg) \
{ \
_xrt_putf("SANITY CHECK: %s %s %s !!\n", \
#aarg, #rel, #bbarg); \
_xrt_putf("%s=%d %16x, %s=%d %16x\n", \
#aarg,aarg,aarg,#bbarg,bbarg,bbarg); \
GTRACEBACK(); \
exit(1); \
}
#define BUFCHK(fio,bits) \
{ \
char *BCXbuflim, *BCXcurdat, *BCXptr, *BCXbase; \
\
BCXbase = BPTR2CP((fio)->_base); \
BCXptr = BPTR2CP((fio)->_ptr); \
SANITYCHK(BCXptr,LT,BCXbase); \
BCXbuflim = BPTR2CP((fio)->_base) + (fio)->_ffbufsiz; \
BCXcurdat = BPTR2CP((fio)->_ptr) + ((bits) >> 3); \
SANITYCHK(BCXcurdat,GT,BCXbuflim); \
}
#else
#define DUMP_IOB(fio) /* no-op */
#define SANITYCHK(a,rel,b) /* no-op */
#define BUFCHK(fio,bits) /* no-op */
#endif
/*
* READBLK()
* Read one block from the next lower layer.
* Data is read in at fio->_ptr.
*/
#define READBLK(retval,fio,nbytes,stat,fulp,ubc) \
{ \
struct fdinfo *RBllfio; \
\
SANITYCHK((nbytes),LT,0); \
RBllfio = (fio)->fioptr; \
retval = XRCALL(RBllfio,readrtn) \
(RBllfio), /* fd of nxt lvl */ \
(fio)->_ptr, \
(nbytes), \
(stat), \
(fulp), \
(ubc)); \
(fio)->_cnt = 0; \
if (retval > 0) \
{ \
(fio)->_cnt = (retval << 3) - *(ubc); \
} \
}
/*
* WRITEBLK()
* Write one block from the buffer to the next lower layer
*/
#define WRITEBLK(retval,fio,nbytes,stat,fulp,ubc) \
{ \
struct fdinfo *WBllfio; \
\
SANITYCHK((nbytes),LT,0); \
WBllfio = (fio)->fioptr; \
retval = XRCALL(WBllfio, writertn) \
(WBllfio),/* fd of nxt lvl */ \
(fio)->_base, /* addr of buf */ \
(nbytes), \
(stat), \
(fulp), \
(ubc)); \
if ((retval) >= 0) \
{ \
(fio)->_cnt = 0; \
(fio)->_ptr = (fio)->_base; \
(fio)->segbits = 0; \
} \
}
/*
* SKIP_BITS()
* on reading, skip the given number of bits by adjusting counters
*/
#define SKIP_BITS(xfio,xnbits) \
{ \
register int SKBtemp; \
SKBtemp = (xnbits); \
SET_BPTR((xfio)->_ptr, \
INC_BPTR((xfio)->_ptr,SKBtemp)); \
(xfio)->segbits -= SKBtemp; \
(xfio)->_cnt -= SKBtemp; \
}
/*
* Get data from buffer and update pointers
*/
#define GETDATA(bufptr, xfio, xnbits) \
{ \
register int GTDtemp; \
GTDtemp = (xnbits); \
BUFCHK((xfio),(GTDtemp)); \
MOV_BITS((bufptr), (xfio)->_ptr, (GTDtemp)); \
SKIP_BITS((xfio),(GTDtemp)); \
}
/*
* Put the data in the buffer from the UDA
*/
#define PUTDATA(bufptr, xfio, xnbits) \
{ \
register long PTDtemp; \
PTDtemp = (xnbits); \
BUFCHK((xfio),(PTDtemp)); \
MOV_BITS((xfio)->_ptr, (bufptr), (PTDtemp)); \
SET_BPTR((xfio)->_ptr, \
INC_BPTR((xfio)->_ptr,(PTDtemp))); \
(xfio)->segbits += (PTDtemp); \
(xfio)->_cnt += (PTDtemp); \
}
/*
* Get a small number of bits where it is not justified to call MOVBIT
* The resultant bits are left justified in the word.
* No checking is done. POINTERS AND COUNTS ARE NOT INCREMENTED
* nbits MUST be <= 64. When sizeof(long) == 64, 64 bits are always
* returned. When sizeof(long) == 32, 32 bits are always returned.
*/
#if defined(__mips) || defined(_LITTLE_ENDIAN)
#define GET_BITS(outword,bufptr,nbits) \
{ \
register int qzshft; \
qzshft = BPBITOFF(bufptr); \
SANITYCHK((nbits),GT,64); \
SANITYCHK((nbits),LT,1); \
if (((qzshft & 07)== 0) && (((nbits) & 07) == 0)) \
{ \
char *_op; \
char *_bp; \
int _iz; \
_bp = BPTR2CP(bufptr); \
_op = (char *)&(outword); \
(outword) = 0; \
for (_iz = 0; _iz < (nbits)/8; _iz++) \
{ \
*_op++ = *_bp++; \
} \
} \
else \
{ \
(outword) = _dshiftl(*BPTR2WP(bufptr), \
*(BPTR2WP(bufptr)+1), \
qzshft) \
& _mask(nbits); /* mask from left */ \
} \
}
#else
#define GET_BITS(outword,bufptr,nbits) \
{ \
register int qzshft; \
qzshft = BPBITOFF(bufptr); \
SANITYCHK((nbits),GT,64); \
SANITYCHK((nbits),LT,1); \
(outword) = _dshiftl(*BPTR2WP(bufptr), \
*(BPTR2WP(bufptr)+1), \
qzshft) \
& _mask(nbits); /* mask from left */ \
}
#endif
#if defined(__mips) || defined(_LITTLE_ENDIAN)
#define PUT_BITS(bufptr,idata,nbits) \
{ \
long P_Btmp1, P_Btmp2, *P_Bp; \
int P_Boff; \
P_Boff = BPBITOFF(bufptr); \
if (((P_Boff & 07) == 0) && (((nbits)&07) == 0)) \
{ \
char *P_Bz; \
int __i; \
P_Bz = BPTR2CP(bufptr); \
for (__i = 0; __i < (nbits)/8; __i++) \
*P_Bz++ = ((unsigned long)(idata) >> ((sizeof(long) -(__i+1))*8)) & 0xff; \
} \
else \
{ \
P_Bp = BPTR2WP(bufptr); \
if ((P_Boff+(nbits)) <= _BITS_PER_LONG) \
{ \
P_Btmp1 = 0; \
P_Btmp2 = 0; \
if (P_Boff != 0) \
P_Btmp1 = (unsigned long)*P_Bp >> \
(_BITS_PER_LONG - P_Boff); \
if ((P_Boff + (nbits)) != _BITS_PER_LONG) \
P_Btmp2 = *P_Bp << (P_Boff + (nbits)); \
P_Btmp1 = _dshiftl(P_Btmp1, idata, (nbits)); \
*P_Bp = _dshiftl(P_Btmp1, P_Btmp2, \
_BITS_PER_LONG - (P_Boff + (nbits))); \
} \
else \
{ \
P_Btmp1 = (unsigned long)*P_Bp >> \
(_BITS_PER_LONG - P_Boff); \
P_Btmp2 = *(P_Bp + 1) << (P_Boff+(nbits)-_BITS_PER_LONG);\
*P_Bp = _dshiftl(P_Btmp1, (idata), _BITS_PER_LONG-P_Boff);\
P_Btmp1 = _dshiftl(P_Btmp1, (idata), (nbits)); \
*(P_Bp+1) = _dshiftr(P_Btmp1, P_Btmp2, \
P_Boff + (nbits) - _BITS_PER_LONG);\
} \
} \
}
#else
/*
* PUT_BITS
* Put a small number of bits (idata) in a specified place. (bufptr)
* input data is left justified in the word.
* This works only if the number of bits is less than 64.
* No checking is done. POINTERS AND COUNTS ARE NOT INCREMENTED
* This means that it works to put a few bits in place where there
* is surrounding data (backpatching)
* For 64-bit architectures, we assume idata is a 64-bit word.
* For 32-bit architectures, we assume idata is a 32-bit word.
*/
#define PUT_BITS(bufptr,idata,nbits) \
{ \
long P_Btmp1, P_Btmp2, *P_Bp; \
int P_Boff; \
P_Boff = BPBITOFF(bufptr); \
P_Bp = BPTR2WP(bufptr); \
if ((P_Boff+(nbits)) <= _BITS_PER_LONG) \
{ \
P_Btmp1 = 0; \
P_Btmp2 = 0; \
if (P_Boff != 0) \
P_Btmp1 = (unsigned long)*P_Bp >> \
(_BITS_PER_LONG - P_Boff); \
if ((P_Boff + (nbits)) != _BITS_PER_LONG) \
P_Btmp2 = *P_Bp << (P_Boff + (nbits)); \
P_Btmp1 = _dshiftl(P_Btmp1, idata, (nbits)); \
*P_Bp = _dshiftl(P_Btmp1, P_Btmp2, \
_BITS_PER_LONG - (P_Boff + (nbits))); \
} \
else \
{ \
P_Btmp1 = (unsigned long)*P_Bp >> \
(_BITS_PER_LONG - P_Boff); \
P_Btmp2 = *(P_Bp + 1) << (P_Boff+(nbits)-_BITS_PER_LONG);\
*P_Bp = _dshiftl(P_Btmp1, (idata), _BITS_PER_LONG-P_Boff);\
P_Btmp1 = _dshiftl(P_Btmp1, (idata), (nbits)); \
*(P_Bp+1) = _dshiftr(P_Btmp1, P_Btmp2, \
P_Boff + (nbits) - _BITS_PER_LONG);\
} \
}
#endif
/*
* MOV_BITS
* Move the specified bits from a_a to b_b.
*/
#if defined(__mips) || defined(_SOLARIS) || defined(_LITTLE_ENDIAN)
#define MOVBIT movbit_
#define MOVBITZ movbitz_
#endif
#ifdef _ABSOFT
#define MOVBIT movbit
#define MOVBITZ movbitz
#endif
extern void _memwcpy(long *_s, long *_s0, int _n);
#if defined(__mips) || defined(_LITTLE_ENDIAN)
#define _MOVEM(to_b, frm_a, nbits) \
{ \
long long M_aoff, M_boff; \
M_aoff = BPBITOFF(frm_a); \
M_boff = BPBITOFF(to_b); \
if (((M_aoff & 07) | (M_boff & 07) | \
(nbits & 07)) == 0 ) \
{ \
memcpy(BPTR2CP(to_b), BPTR2CP(frm_a), \
(nbits) / 8); \
} \
else \
{ \
long long M_Bits; \
\
M_Bits = (nbits); \
M_aoff = BPBITOFF(frm_a); \
M_boff = BPBITOFF(to_b); \
SANITYCHK(M_aoff,GT,_BITS_PER_LONG) \
SANITYCHK(M_aoff,GT,_BITS_PER_LONG) \
MOVBITZ(BPTR2WP(frm_a), &M_aoff, \
&M_Bits, BPTR2WP(to_b), &M_boff);\
} \
}
#else
#define _MOVEM(to_b, frm_a, nbits) \
{ \
if ((BPBITOFF(frm_a) | BPBITOFF(to_b) | \
(nbits & 077)) == 0 ) \
{ \
_memwcpy(BPTR2WP(to_b), BPTR2WP(frm_a), \
(nbits) / _BITS_PER_LONG); \
} \
else \
{ \
long M_aoff, M_boff, M_Bits; \
\
M_Bits = (nbits); \
M_aoff = BPBITOFF(frm_a); \
M_boff = BPBITOFF(to_b); \
SANITYCHK(M_aoff,GT,_BITS_PER_LONG) \
SANITYCHK(M_aoff,GT,_BITS_PER_LONG) \
MOVBITZ(BPTR2WP(frm_a), &M_aoff, \
&M_Bits, BPTR2WP(to_b), &M_boff);\
} \
}
#endif
#define MOV_BITS(to_b,frm_a,bits) \
{ \
SANITYCHK(BPTR2WP(frm_a),LE,(long *)100) \
SANITYCHK(BPTR2WP(to_b),LE,(long *)100) \
_MOVEM(to_b, frm_a, bits); \
}
/*
* Clear the status word. These macros clear the iosw and ffsw structures.
* Note that only the first three words of the ffsw are cleared. This is
* because the fourth word is new in UNICOS 7.0, and for safety is not used.
* On machines where _ADDR64 is true (and MIPS), more space is cleared.
*/
#if defined(__mips) || defined(_LITTLE_ENDIAN)
#define CLRSTAT(io_sw) {*(int *)&(io_sw) = 0; io_sw.sw_count=0;}
#else
#define CLRSTAT(io_sw) *(long *)&(io_sw) = 0
#endif
#if defined(__mips) || defined(_LITTLE_ENDIAN)
/* Clear through sw_sptr */
#define CLRFFSTAT(io_sw) \
{ \
long *_ptr; \
_ptr = (long *)&(io_sw); \
*_ptr++ = 0; \
*_ptr++ = 0; \
*_ptr++ = 0; \
*_ptr++ = 0; \
*_ptr++ = 0; \
*_ptr++ = 0; \
}
#elif defined(_ADDR64)
#define CLRFFSTAT(io_sw) \
{ \
long *_ptr; \
_ptr = (long *)&(io_sw); \
*_ptr++ = 0; \
*_ptr++ = 0; \
*_ptr++ = 0; \
*_ptr++ = 0; \
}
#else
#define CLRFFSTAT(io_sw) \
{ \
long *_ptr; \
_ptr = (long *)&(io_sw); \
*_ptr++ = 0; \
*_ptr++ = 0; \
*_ptr++ = 0; \
}
#endif
#if defined(DEBUG) && !defined(__mips) && !defined(_LITTLE_ENDIAN)
#define _STATPRINT(trcvar, nstat) \
{ \
if (FDCTRACE(TRACE_STATUS)) \
{ \
char _str[128]; \
\
sprintf(_str, \
"SETSTAT: %d, at line number %d in file %s\n", \
nstat, __LINE__, __FILE__); \
_xrt_putstr(_str); \
} \
}
#define _ERRPRINT(trcvar, errnum) \
{ \
if (FDCTRACE(TRACE_STATUS)) \
{ \
char _str[128]; \
\
sprintf(_str, \
"SETERROR: %d, at line number %d in file %s\n", \
errnum, __LINE__, __FILE__); \
_xrt_putstr(_str); \
} \
}
#else
#define _STATPRINT(trcvar, nstat)
#define _ERRPRINT(trcvar, errnum)
#endif
/*
* Set the status field in the status struct.
*/
#define _SETSTAT(io_sw,nstat,nbytes) { \
(io_sw)->sw_flag = 1; \
(io_sw)->sw_error = 0; \
(io_sw)->sw_count = (nbytes); \
(io_sw)->sw_stat = (nstat); \
}
/*
* Set the error status. Always print the error in DEBUG mode
*/
#define _SETERROR(io_sw,errnum,nbytes) { \
(io_sw)->sw_flag = 1; \
(io_sw)->sw_error = (errnum); \
(io_sw)->sw_count = (nbytes); \
FFSTAT(*io_sw) = FFERR; \
_ERRPRINT(TRACE_STATUS,errnum); \
}
#define SETSTAT(io_sw,nstat,nbytes) { \
_SETSTAT(io_sw,nstat,nbytes); \
_STATPRINT(__fdctrace_enable,nstat); \
}
/*
* Set the status and return an error. Always print the status in DEBUG mode
*/
#define ERETURN(io_sw,errnum,nbytes) { \
_SETERROR(io_sw,errnum,nbytes); \
return(ERR); \
}
#if !defined(__mips) && !defined(_LITTLE_ENDIAN)
#define _FFOPEN_ERETURN(_a,_b,_c) ERETURN((_a),(_b),(_c))
#define _FFOPEN_ERR ERR
#else
#define _FFOPEN_ERR (_ffopen_t) -1L
#define _FFOPEN_ERETURN(_a,_b,_c) { \
_SETERROR((_a),(_b),(_c)); \
return(_FFOPEN_ERR); }
#endif
/*
* These are the 'generic' SCC codes. They are the ones that
* are used internally and translated into those for IBM and VMS
* Having the FULL code =0 has the advantage if no SCCs need to be
* processed.
*/
#define SCCUNKN -1 /* This does not translate into a 'real' SCC code */
#define SCCFULL 0
#define SCCFRST 1
#define SCCLAST 2
#define SCCMIDL 3
/*
* segment control code definitions fr all classes
*/
#define SCC_IBM 0 /* IBM type Segment Control code */
#define SCC_VMS 1 /* VMS type Segment Control code */
#define SCC_CDC 2 /* CDC type Segment Control code */
#define SCC_NVE 3 /* CDC type Segment Control code */
/*
* Number of SCC types. This is for the scc table dimension
*/
#define NUM_SCC_TYPES 4 /* IBM, VMS and CDC, and NOS/VE*/
/*
* error codes for FDC parameters while parsing the -F assign attribute.
*/
#define FDC_PERR_CLASS 1
#define FDC_PERR_RFC 2
#define FDC_PERR_RFCS 3
#define FDC_PERR_RSZ 4
#define FDC_PERR_MBS 5
#define FDC_PERR_MIN 6
#define FDC_PERR_MAX 7
#define FDC_PERR_INC 8
#define FDC_PERR_BAD 9
#define NUM_PERRS 9
/*
* fddcvrt_u: foreign dataset data conversion descriptor word.
* This word contains fields that describe the users
* request for data conversion.
*
*
* 0 64
* /--------+--------+--------+----------------------------------------\
* |vers | bin | char | |
* |info | cvrt | set | unused ...(40 bits) |
* | 8 bits | 8 bits | 8 bits | |
* \--------+--------+--------+----------------------------------------/
* ^ ^ ^
* zero ^ ^
* for ^ ^
* now ^ ^
* ^ ^
* ^ ^
* ^ ^
* ^ ^
* ^ ^
* ^ 1=ascii
* ^ 2=ebcdic
* ^ etc...
* ^
* 2=binary - IBM
* 3=binary - CDC
* etc..
*/
union fddcvrt_u
{
struct
{
int vers:8; /* version ID, zero for now */
int cvrt:8; /* numeric conversion code */
int cvch:8; /* character conversion code */
int cvch_opt:8; /* text record options */
int unused:32;
} fld;
unsigned long wword;
};
/*
* spec_u:
*
* FFIO specification word. A sequence of one or more of consecutive
* spec_u words is used to pass FFIO layer parameters to any layer's
* open routine.
*
* The first 8 bits of each spec_u word contain the extension bit and the
* class. The extension bit is set in all but the last spec_u word
* in a spec_u word sequence.
*
* The remainder of each word can contain different info depending on
* class.
*
* Before changing spec_u, be sure the new structure will maintain
* compatibility between new versions of the asgcmd command and old
* libraries.
*
* Starting in UNICOS 7.0, a "standard default sequence" of spec_u words
* is used for most layers. The sequence generated by layer specification
*
* layer.str1.str2:num1:num2:num3:...:numN
*
* is:
*
* Word 0 (hdr):
* -------------
* 0 64
* /-+-+-----+--------+----+----+--------------------+--------------------\
* |e| |class| str1 |str2| unused |
* |x| | | | | |
* |t| |6-bit| 8-bits |4bit| 44-bits |
* \-+-+-----+--------+----+----+--------------------+--------------------/
*
* Words 1..N (info):
* ------------------
* 0 64
* /-+-+-----+--------+----+----+--------------------+--------------------\
* |e|v|class| value |
* |x|a| | |
* |t|l|6-bit| 56-bits |
* \-+-+-----+--------+----+----+--------------------+--------------------/
*
*
* Spec_u word format used for SDS and MR layers:
*
* Word 0 (fss):
* -------------
* 0 64
* /-+-+-----+--------+----+----+--------------------+--------------------\
* |e| |class| recfmt |styp| | min |
* |x| | | | | | |
* |t| |6-bit| 8-bits |4bit| | 40-bits |
* \-+-+-----+--------+----+----+--------------------+--------------------/
*
*
* Spec_u word 0 format used for compatibility between asgcmd and old libraries:
*
* Word 0 (fld):
* -------------
* 0 64
* /-+-+-----+--------+----+----+--------------------+--------------------\
* |e| |class| recfmt |styp| | recsize | mbs |
* |x| | | | | | | |
* |t| |6-bit| 8-bits |4bit| | 20-bits | 20-bits |
* \-+-+-----+--------+----+----+--------------------+--------------------/
*
* Spec_u word 0 format used by new assign parser
*
* Word 0 (fld):
* -------------
* 0 64
* /-+-+-----+--------+----+----+--------------------+--------------------\
* |e| |class| info | recsize | mbs |
* |x| | | | | | |
* |t| |6-bit| 12-bits | | 20-bits | 20-bits |
* \-+-+-----+--------+----+----+--------------------+--------------------/
*/
#if defined(_CRAY) || defined(__mips) || defined(_LITTLE_ENDIAN)
/*
#ifndef uint64
#define uint64 unsigned long long
#endif
#ifndef int64
#define int64 long long
#endif
*/
typedef uint64 _spect; /* 64-bit unsigned integer */
#else
typedef unsigned _spect;
#endif
union spec_u
{
struct
{
_spect ext :1; /* ext bit is on if not end of spec */
_spect :1;
#ifndef __cplusplus
_spect class :6; /* ffio CLASS */
#else
_spect classsp :6; /* ffio CLASS */
#endif
_spect str1 :8; /* string parameter 1 */
_spect str2 :4; /* string parameter 2 */
} hdr;
struct
{
_spect ext :1; /* set to 1 if not end of spec */
_spect valid :1; /* set to 1 if this param was passed */
#ifndef __cplusplus
_spect class :6; /* ffio CLASS */
#else
_spect classsp :6; /* ffio CLASS */
#endif
#if defined(_WORD32) && !defined(__mips) && !defined(_LITTLE_ENDIAN)
unsigned quan; /* numeric parameter value */
#else
_spect quan :56; /* numeric parameter value */
#endif
} info;
struct
{
_spect ext :1; /* ext bit is on if not end of spec */
_spect :1;
#ifndef __cplusplus
_spect class :6; /* ffio CLASS */
#else
_spect classsp :6; /* ffio CLASS */
#endif
_spect recfmt :8; /* This is the record format */
_spect subtype :4; /* record format subtype. */
#if defined(_WORD32) && !defined(__mips) && !defined(_LITTLE_ENDIAN)
unsigned min;
#else
_spect :4;
_spect min :40;
#endif
} fss;
struct
{
_spect ext :1; /* ext bit is on if not end of spec */
_spect unused1 :1;
#ifndef __cplusplus
_spect class :6; /* ffio CLASS */
#else
_spect cpasssp :6; /* ffio CLASS */
#endif
_spect recfmt :8; /* This is the record format */
_spect subtype :4; /* record format subtype. */
_spect :4;
_spect recsize :20;
_spect mbs :20;
} fld;
struct
{
_spect ext :1; /* ext bit is on if not end of spec */
_spect unused1 :1;
#ifndef __cplusplus
_spect class :6; /* ffio CLASS */
#else
_spect cpasssp :6; /* ffio CLASS */
#endif
_spect info1 :24; /* This contains non-numeric info */
_spect info2 :32; /* This contains more non-numeric info */
} class_info;
#if defined(_CRAY) || defined(__mips) || defined(_LITTLE_ENDIAN)
_spect wword;
#elif defined(_WORD32)
unsigned long long wword;
#else
#error "THIS CASE IS NOT HANDLED"
#endif
};
/*
* Find the next start of spec..
* Skip the extension words.
*/
#define NEXT_SPEC(nxtspec) { nxtspec = _next_spec(nxtspec); }
#include <cray/mtlock.h>
/*
* Global open information packet. This structure contains information
* intended to be shared by all FFIO layers in a chain.
*/
struct gl_o_inf {
int version; /* version number for gl_o_inf */
/* structure. Is 0 in 8.1+ libraries */
enum {
OT_FORTRAN=1,
OT_USER1=2,
OT_USER2=4,
OT_USER3=8,
OT_USER4=16,
OT_USER5=32,
OT_USER6=64,
OT_USER7=128,
OT_USER8=256,
OT_USER9=512,
OT_SSIO=1024
} open_type; /* code for type of open */
union {
struct { /* for Fortran files ... */
unum_t unum; /* unit number (-1 if unknown) */
unsigned is_seq:1; /* 1 iff access='sequential' */
unsigned is_fmt:1; /* 1 iff form='formatted' */
long reclen; /* 0 or RECL= value */
} fort;
int pad_a[15]; /* pad for future expansion */
} u;
unsigned alreadyopen:1; /* 1 iff file is already opened and */
/* "fd" contains file descriptor. */
/* Used only by _gsys_open and */
/* _bmx_open. */
int fd; /* file descriptor of already-open */
/* tape file. */
int depth; /* FFIO layer depth (1 == top level)*/
struct assign_info_s
*aip; /* assign info, or NULL */
int pad_b[4]; /* pad for future expansion */
int64 user[2]; /* reserved for user layers */
int64 site[2]; /* reserved for site layers */
};
/*
* This structure defines the function pointers that comprise the standard
* interface that is used between layers of the FDC process.
*/
#if defined(__mips) || defined(_LITTLE_ENDIAN)
typedef struct fdinfo * _ffopen_t;
typedef off_t _ffseek_t;
#else
typedef int _ffopen_t;
typedef int _ffseek_t;
#endif
#if defined(__mips) || defined(_LITTLE_ENDIAN)
#define ___(A) A
#else
#define ___(A) ()
#endif
struct xtr_s
{
/* Specific open processing for the file type */
_ffopen_t (* openrtn) ___((const char *_Name, int _Flags, mode_t _Mode, struct fdinfo *_Fio, union spec_u *_Spec, struct ffsw *_Retstat, long _Cbits, int _Cblks, struct gl_o_inf *_Oinf));
/* Read one block/record of data packed */
ssize_t (* readrtn) ___((struct fdinfo *_Fio, bitptr _Bufptr, size_t _Nbytes, struct ffsw *_Retstat, int _Fulp, int *_Ubc));
/* Read one block/record of data async */
ssize_t (* readartn) ___((struct fdinfo *_Fio, bitptr _Bufptr, size_t _Nbytes, struct ffsw *_Retstat, int _Fulp, int *_Ubc));
/* Read one block/record of data 1 char/wd */
ssize_t (* readcrtn) ___((struct fdinfo *fio, bitptr _Bufptr, size_t _Nbytes, struct ffsw *_Restat, int _Fulp));
/* Write one block/record of data packed */
ssize_t (* writertn) ___((struct fdinfo *_Fio, bitptr _Bufptr, size_t _Nbytes, struct ffsw *_Retstat, int _Fulp, int *_Ubc));
/* Write one block/record of data async */
ssize_t (* writeartn) ___((struct fdinfo *_Fio, bitptr _Bufptr, size_t _Nbytes, struct ffsw *_Retstat, int _Fulp, int *_Ubc));
/* Write one block/record of data 1 char/wd */
ssize_t (* writecrtn) ___((struct fdinfo *_Fio, bitptr _Bufptr, size_t _Nbytes, struct ffsw *_Restat, int _Fulp));
/* Do any special cleanup and close file */
int (* closertn) ___((struct fdinfo *_Fio, struct ffsw *_Retstat));
/* Flush the buffers */
int (* flushrtn) ___((struct fdinfo *_Fio, struct ffsw *_Retstat));
/* endfile routine, not always meaningful */
int (* weofrtn) ___((struct fdinfo *_Fio, struct ffsw *_Retstat));
/* end of data routine "the REAL end" */
int (* weodrtn) ___((struct fdinfo *_Fio, struct ffsw *_Retstat));
/* seek on foreign file?? */
_ffseek_t (* seekrtn) ___((struct fdinfo *_Fio, off_t _Pos, int whence, struct ffsw *_Retstat));
/* backspace routine */
int (* backrtn) ___((struct fdinfo *_Fio, struct ffsw *_Retstat));
/* positioning routine */
_ffseek_t (* posrtn) ___((struct fdinfo *_Fio, int _Cmd, void *_Arg, int _Len, struct ffsw *_Stat));
/* listio routine */
int (* listiortn) ___((int _Cmd, struct fflistreq *_List, int _Nent, struct ffsw *_Stat));
int (* fcntlrtn) ___((struct fdinfo *_Fio, int _Cmd, void *_Arg, struct ffsw *_Stat)); /* fcntl routine */
};
/*
* Remove definition of ___
*/
#undef ___
/*
* the fdinfo block is a sort of 'DSP' for FDC. It contains all of the
* state information used by the various routines.
*/
struct fdinfo
{
long magic; /* magic number for ID */
int realfd; /* Our real file descriptor number */
/* this is only used by layers that have */
/* either private implementations, or */
/* 'real' file descriptors. */
struct fdinfo *fioptr; /* Pointer to fdinfo block for next */
/* lower level. */
struct fdinfo *parptr; /* Pointer to fdinfo block for parent layer */
struct stat *lstp; /* Pointer to result of last stat/ffstat call */
/* If null, none has been done */
long opn_flags; /* Flags used in open call */
/*
* info about blocks and records
*/
int subtype; /* record subtype (block type for CDC) */
int64 maxrecsize; /* max record size in BITS */
int64 maxblksize; /* Maximum Block Size (MBS) in BITS */
#ifndef __cplusplus
int class; /* record translation class */
#else
int classfdinfo; /* record translation class */
#endif
int rtype; /* Record type, as defined above */
/*
* Counters. These are the counts of data and such in the buffer(s).
* Note: All counts are kept and passed in bits.
*/
int64 recbits; /* total number of bits in logical record */
/* This is only valid after a partial read */
/* or write. It is reset at each EOR/EOF */
long segbits; /* number of bits left in segment */
/* This always indicates the amount */
/* of 'clear' data to be processed. */
/* on write, this is the number of bits */
/* already in the buffer, on read, the */
/* number left in the buffer */
int scc; /* segment control code */
int lastscc; /* segment control code for prev. segment. */
int64 last_recbits; /* record length of last record in BITS */
/* This is used differently in various layers */
/*
* Buffer info
*/
bitptr _base; /* BIT pointer */
bitptr _ptr; /* BIT pointer to next data in buffer */
long _cnt; /* BIT count. Bits left in buffer on read*/
/* Bits accumulated on write */
long _ffbufsiz; /* BIT size of buffer */
/*
* Flags
*/
int rwflag; /* 4 for position, 2 for write, 1 for read */
/* This tells what the last operation was, */
/* nothing about open mode(s) */
unsigned atbod:1; /* _TRUE if at beginning of data */
unsigned ateor:1; /* _TRUE if at end of record */
unsigned ateof:1; /* _TRUE if EOF was last op (read or write) */
unsigned ateod:1; /* _TRUE if EOD was last op (read or write) */
unsigned can_listio:1; /* _TRUE if layer can handle listio */
unsigned lock:1; /* _TRUE if ffxxx routines need to lock */
unsigned reg_lock:1; /* _TRUE if ffxxx rtns use regular locks */
unsigned free_lock:1; /* _TRUE if a lock layer needs to free */
plock_t *lock_word; /* layers request that we use their lock */
int rsv6; /* reserved for CRI */
/*
* Function pointers (!)
*/
struct xtr_s xr; /* pointers to routines that do the work. */
/*
* record type specific information
*/
void *lyr_info; /* private layer info block ptr */
};
/* extern declarations */
extern int __fdctrace_enable; /* debugging flags */
extern int _scc_tab[NUM_SCC_TYPES][4];
/*
* These prototypes are for internal functions which a user may not
* use by default.
*/
#if defined(__mips) || defined(_CRAY) || defined(_LITTLE_ENDIAN)
typedef int64 _nparmtype; /* type of numeric parameters */
#else
typedef int _nparmtype;
#endif
extern _nparmtype _ff_nparm_getv (union spec_u *spec, int parnum, int *isvalid);
extern int _ff_nparm_getcnt (union spec_u *spec);
extern union spec_u *_next_spec(union spec_u *sp);
extern _ffopen_t _ffopen (const char *name, int flags, mode_t mode,
union spec_u *spek, struct ffsw *stat, long cbits, int cblks,
struct fdinfo *pa_fio, struct gl_o_inf *oinf);
extern int _ffopensg(const char *name, int flags, mode_t mode,
long cbits, int cblks, struct ffsw *stat,
const char *cspec, struct gl_o_inf *oinf);
#if defined(__mips) || defined(_LITTLE_ENDIAN)
extern int _ff_fdinfo_to_int(_ffopen_t fd, struct ffsw *pstat);
#else
#define _ff_fdinfo_to_int(fd, pstat) ((int)(fd))
#endif
#endif /* _LIB_INTERNAL */
#if defined(__mips) || defined(_LITTLE_ENDIAN)
__BEGIN_DECLS
extern int ffassign (char *cmd);
extern int ffbksp (int _Fd);
extern int ffclose (int _Fd);
extern ssize_t ffread (int _Fd, void *_Buf, size_t _Nb);
extern ssize_t ffwrite (int _Fd, const void *_Buf, size_t _Nb );
extern off_t ffseek (int _Fd, off_t _Pos, int _Whence );
extern int ffweof (int _Fd);
extern int ffweod (int _Fd);
extern int ffopens (const char *_Name, int _Oflag, mode_t _Mode, long _Cbits,
int _Cblks, struct ffsw *_Stat, const char *_Str);
extern int fffcntl (int _Fd, int _Cmd, void *_Arg, struct ffsw *_Stat);
extern off_t ffpos (int _Fd, int _Cmd, void *_Arg, int _Len,
struct ffsw *_Stat);
extern int ffflush (int _Fd, struct ffsw *_Stat);
extern char *ffstrerror(int _Errnum);
__END_DECLS
#else
#include <cray/clibinc_config.h>
#if !defined(_CRAYT3E) && _CRAYLIBS_RELEASE < 3000
#define _USE_OLD_PROTOTYPE 1
#endif
__BEGIN_DECLS
extern int ffbksp (int _Fd, ...);
extern int ffclose (int _Fd, ...);
extern int fffcntl (int _Fd, int _Cmd, ...);
extern int ffflush (int _Fd, ...);
extern int fflistio (int _Cmd, struct fflistreq *_List, int _Nent, ...);
extern int ffopens (const char *_Name, int _Oflag, int _Mode, long _Cbits,
... );
extern int ffpos (int _Fd, int _Cmd, long *_Arg, int _Len,
struct ffsw *_Stat);
extern char *ffstrerror(int _Errnum);
#if _USE_OLD_PROTOTYPE
extern int ffread (int _Fd, char *_Buf, int _Nb, ...);
#else
extern int ffread (int _Fd, void *_Buf, size_t _Nb, ...);
#endif
extern int ffreada (int _Fd, char *_Buf, int _Nb, struct ffsw *_Stat, ...);
extern int ffreadc (int _Fd, char *_Buf, int _Nb, ...);
#if _USE_OLD_PROTOTYPE
extern int ffseek (int _Fd, int _Pos, int _Whence, ...);
#else
extern int ffseek (int _Fd, off_t _Pos, int _Whence, ...);
#endif
extern int ffsetsp (int _Fd, ...);
extern int ffweod (int _Fd, ...);
extern int ffweof (int _Fd, ...);
#if _USE_OLD_PROTOTYPE
extern int ffwrite (int _Fd, char *_Buf, int _Nb, ...);
#else
extern int ffwrite (int _Fd, const void *_Buf, size_t _Nb, ...);
#endif
extern int ffwritea (int _Fd, char *_Buf, int _Nb, struct ffsw *_Stat, ...);
extern int ffwritec (int _Fd, char *_Buf, int _Nb, ...);
__END_DECLS
#endif
__BEGIN_DECLS
extern int ffbkspf (int _Fd, struct ffsw *_Stat);
extern int ffopen (const char *_Name, int _Oflag, ...);
extern int ffopenf (const char *_Name, int _Oflag, mode_t _Mode, long _Cbits,
int _Cblks, struct ffsw *_Pstat);
extern int ffiolock (int _fd, struct ffsw *_Stat);
extern int ffiounlock (int _fd, struct ffsw *_Stat);
extern int ffclosef (int _Fd, struct ffsw *_Stat);
extern int ffweoff (int _Fd, struct ffsw *_Stat);
extern int ffweodf (int _Fd, struct ffsw *_Stat);
extern off_t ffseekf (int _Fd, off_t _Pos, int _Whence, struct ffsw *_Stat);
extern ssize_t ffreadf (int _Fd, void *_Buf, size_t _Nb, struct ffsw *_stat, int _Fulp, int *_Ubc);
extern ssize_t ffwritef (int _Fd, const void *_Buf, size_t _Nb, struct ffsw *_stat, int _Fulp, int *_Ubc);
__END_DECLS
#endif /* !_FFIO_H */